#==================================================
#	Plugin
#==================================================
# 代码编辑器菜单按钮插件
#==================================================
# @path: res://addons/code_editor_menu_button/plugin.gd
# @datetime: 2021-6-23 22:26:11
#==================================================
tool
extends EditorPlugin


var util = _CodeEditorUtil.new()

# 插件节点
var menu_button = _CodeEditor_MenuButton.new(get_button_name())

# 子插件列表
var sub_plugin_list : Dictionary = {}


#==================================================
#   Set/Get
#==================================================
func get_button_name():
	if OS.get_locale_language() == 'zh':
		return "代码"
	else:
		return "Source"


#==================================================
#   内置方法
#==================================================
func _enter_tree():
	util.set_plugin(self)
	
	# 设置属性
	menu_button.name = get_button_name() 
	menu_button.set_meta("CodeEditorMenuButton", true)
	# 添加菜单按钮到编辑器当中
	util.script_editor_util.add_menu_button(menu_button)
	
	# 初始化子插件
	init_sub_plugin([
		_CodeEditor_SubPlugin_AddCommonts.new(),
		# 列表时这两个之间不添加分隔符，单个写出来会添加分隔符
		[_CodeEditor_SubPlugin_OverrideMethod.new(),
			_CodeEditor_SubPlugin_Setget.new(),
		],
		_CodeEditor_SubPlugin_NodePath.new(),
		# 其他调用用到外部脚本的插件
		[_CodeEditor_SubPlugin_OtherExternal_Wrapper.new(),
			_CodeEditor_SubPlugin_OtherExternal_ChainAttribute.new(),
			_CodeEditor_SubPlugin_OtherExternal_StateMachine.new(),
		],
	], true)
	
	# 添加关闭插件菜单项
	menu_button.add_popup_item("重新加载插件", self, "reload_plugin")
	menu_button.add_popup_item("关闭插件", self, "close_plugin")


func _exit_tree():
	_remove_menu_button()
	for sub_plugin in sub_plugin_list.keys():
		if sub_plugin is _CodeEditor_SubPluginBase:
			sub_plugin.uninstall()
		else:
			printerr("卸载子插件出现错误，添加的不是子插件类型")


#==================================================
#   自定义方法
#==================================================
func init_sub_plugin(plugin_list: Array, add_separa: bool):
	var idx = 0
	for sub_plugin in plugin_list:
		idx += 1
		if sub_plugin is _CodeEditor_SubPluginBase:
			sub_plugin_list[sub_plugin] = null
			sub_plugin._menu_button = menu_button
			sub_plugin.set_plugin(self)
			sub_plugin.init_menu_button()
			# 子项添加分隔符，我让最后一个不能添加
			if add_separa and idx < plugin_list.size():
				menu_button.add_separator()
		elif sub_plugin is Array:
			init_sub_plugin(sub_plugin, false)
	
	# 中间的子项不添加分隔，则循环末尾时添加
	if not add_separa:
		menu_button.add_separator()


##  移除 menu_button 菜单按钮
func _remove_menu_button() -> void:
	# [释放 menu_button]
	# 必须要通过以下这种方式获取 Source 节点，
	# 因为 menu_button 存入变量中的方式
	# 会在修改时失效，造成移除失败
	
	# 获取编辑器视图
	var v_editor = get_editor_interface().get_editor_viewport()
	# 代码编辑器菜单的父节点
	var menu_button_parent = v_editor.get_child(2).get_child(0).get_child(0)
	# 寻找添加的 menu_button 节点，并 queue_free
	for node in menu_button_parent.get_children():
		if node.has_meta("CodeEditorMenuButton"):
			if is_instance_valid(node):
				node.queue_free()


##  关闭插件
func close_plugin():
	# 返回当前脚本所在文件夹，这个文件夹名就是插件名
	var plugin_name = get_current_plugin_name()
	# 插件名与目录名相同
	get_editor_interface().set_plugin_enabled(plugin_name, false)


##  重新加载插件
func reload_plugin():
	var plugin_name = get_current_plugin_name()
	
	print("=".repeat(50))
	print("  [%s] 准备重新加载插件 " % plugin_name)
	
	var interface = get_editor_interface()
	# 移除 menu_button
	_remove_menu_button()
	# 关闭插件
	get_editor_interface().set_plugin_enabled(plugin_name, false)
	# 打开插件
	interface.set_plugin_enabled(plugin_name, true)
	
	print("  [%s] 插件已重新加载" % plugin_name)
	print("=".repeat(50))


##  返回插件名
func get_current_plugin_name():
	return util.script_util.get_script_dir_name(self.get_script())

